package br.ufrgs.meetapp.activities;

import java.util.regex.Pattern;

import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import br.ufrgs.meetapp.dialogs.PopupMessage;
import br.ufrgs.meetapp.enums.WebServiceResult;
import br.ufrgs.meetapp.models.User;
import br.ufrgs.meetapp.utils.ActivityIndicator;
import br.ufrgs.meetapp.utils.UserPreferencesPersistence;
import br.ufrgs.meetapp.webservices.MFTWebServiceClient;

public class RegisterActivity extends Activity implements OnClickListener{
	
	private TextView usernameTextView;
	private TextView passwordTextView;
	private TextView repeatedPasswordTextView;
	private TextView emailTextView;
	private TextView fullnameTextView;
	private TextView phoneTextView;
	private Button registerButton;

	private Drawable originalEditTextDrawable;
	
	private PopupMessage errorPopup;
	private String errorBody;	
	
	WebServiceResult registryResult;
	ActivityIndicator activityIndicator;
	
	private final Pattern EMAIL_ADDRESS_PATTERN = Pattern.compile(
	          "[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" +
	          "\\@" +
	          "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" +
	          "(" +
	          "\\." +
	          "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" +
	          ")+"
	      );
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
	    setContentView(R.layout.register_activity);
	    
	    setTitleBar();
	    inicializeViews();
	}
	
	/**
	 * Initialize the view references
	 */
	private void inicializeViews() {
		//Sets onClickListener for the Register Button
		registerButton = (Button) findViewById(R.id.registerButton);
		registerButton.setOnClickListener(this);
		
		//Reference all text views
		usernameTextView = (TextView) findViewById(R.id.register_activity_text_username);
		passwordTextView = (TextView) findViewById(R.id.register_activity_text_password);
		repeatedPasswordTextView = (TextView) findViewById(R.id.register_activity_text_repeat_password);
		emailTextView = (TextView) findViewById(R.id.register_activity_text_email);
		fullnameTextView = (TextView) findViewById(R.id.register_activity_text_fullname);
		phoneTextView = (TextView) findViewById(R.id.register_activity_text_phone);
		
		originalEditTextDrawable = usernameTextView.getBackground();
		
		activityIndicator = new ActivityIndicator(this);		
	}
	
	/***
	 * Sets the top bar
	 */
	private void setTitleBar() {
		TextView titleBarTitle;
		getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_bar);
		titleBarTitle = (TextView) findViewById(R.id.title_bar_text_title);
		titleBarTitle.setText(R.string.register_title);
	}

	@Override
	public void onClick(View view) {
		switch (view.getId()) {
		case R.id.registerButton:
			verifyRegister();
			break;
		default:
			break;
		}
	}
	
	/**
	 * Create the hard-button menu
	 */
	public boolean onCreateOptionsMenu(Menu menu){
    	super.onCreateOptionsMenu(menu);
    	MenuInflater menuInflater = getMenuInflater();
    	menuInflater.inflate(R.menu.menu_about, menu);
    	return true;
    }
    
	/**
	 * Actions to the hard-button menu
	 */
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menuAbout:
			Intent intent;
			intent = new Intent(getApplicationContext(), AboutActivity.class);
			intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			startActivity(intent);
			return true;
		}

		return false;
	}
	
	/**
	 * Check the data to register a new user and call an Async Task
	 * to send the user information to the WebService
	 */
	private void verifyRegister(){
		resetErrorBorders();
		errorBody = "";
		if(isLocallyValidRegister()){
			new VerifyRegisterTask().execute();
		}
		else{
			setRegistrationFailMessage();
		}
	}
	
	/**
	 * Asynchronous task to call the Web service to register the 
	 * new user. Also show the Activity Indicator
	 */
	private class VerifyRegisterTask extends AsyncTask<Void, Void, Void>{

		private boolean isServerValid;
		
		@Override
		protected void onPreExecute() {
			activityIndicator.show();
		};
		
		@Override
		protected Void doInBackground(Void... params) {
			MFTWebServiceClient webService = new MFTWebServiceClient();
			registryResult = null;
			
			try {
				User registeringUser = new User();
				
				registeringUser.setUsername(usernameTextView.getText().toString());
				registeringUser.setCompanyName(usernameTextView.getText().toString());
				registeringUser.setPassword(passwordTextView.getText().toString());
				registeringUser.setEmail(emailTextView.getText().toString());
				registeringUser.setFullName(fullnameTextView.getText().toString());
				registeringUser.setPhone(phoneTextView.getText().toString());
				
				registryResult = webService.registerUser(registeringUser);
			
			} catch (Exception e) {
				System.out.println("Error in RegisterActivity.VerifyLoginTask.doInBackground - trying to call login service");

				if (e.getMessage() != null) {
					System.out.println(e.getMessage());
				}

				e.printStackTrace();
			}
			
			if (registryResult != null && registryResult == WebServiceResult.OK) {
				isServerValid = true;
			} else {
				isServerValid = false;
			}

			return null;
		}
		

		@Override
		protected void onPostExecute(Void result) {
			if (isServerValid) {
				activityIndicator.dismiss();
				setRegistrationSuccessful();	
			} else {
				setServerError();
				setRegistrationFailMessage();
			}
			super.onPostExecute(result);
		}
		
	}
	
	/**
	 * Dismiss the Activity indicator and show the error pop up
	 */
	private void setRegistrationFailMessage() {
		activityIndicator.dismiss();
		errorPopup = new PopupMessage(this,
				getString(R.string.register_error), errorBody,
				getString(R.string.ok_button), null);
		errorPopup.display();		
	}
	
	/**
	 * Called when the registration is successful. 
	 * Updates user preferences and navigate to Login Screen.
	 */
	private void setRegistrationSuccessful() {
		Toast.makeText(getApplicationContext(), R.string.registration_successful, Toast.LENGTH_LONG).show();
		
		UserPreferencesPersistence.setUserName(this, usernameTextView.getText().toString());
		UserPreferencesPersistence.setCustomer(this, usernameTextView.getText().toString());
		UserPreferencesPersistence.setPassword(this, passwordTextView.getText().toString());
		UserPreferencesPersistence.setLoginOnce(this, true);
		UserPreferencesPersistence.setLoginType(this, LoginActivity.LOGIN_TYPE_CONSUMER);
		
		finish();
	}
	

	/**
	 * Verify if the user data is consistent. 
	 * Check if Name, Passwords and email are valids.
	 * 
	 * @return True if is LocallyValid and False if isn't
	 */
	private boolean isLocallyValidRegister(){
		boolean isLocallyValid = true;

		resetErrorBorders();

		if (usernameTextView.getText().toString().equals("")) {
			setUserNameError();
			isLocallyValid = false;
		}


		String password = passwordTextView.getText().toString();
		if (password.length() > 5){
			
			int numberOfLetters = 0;
			int numberOfDigits = 0;
			
			for(int i=0; i < password.length(); i++){
				if (Character.isDigit(password.charAt(i))){
					numberOfDigits++;
				} else if (Character.isLetter(password.charAt(i))){
					numberOfLetters++;
				}
			}
			
			if (numberOfLetters < 5 || numberOfDigits < 1){
				setPasswordError();
				isLocallyValid = false;
			}else if (!password.equals(repeatedPasswordTextView.getText().toString())){
				setRepeatedPasswordError();
				isLocallyValid = false;
			}	
		}else {
			setPasswordError();
			isLocallyValid = false;
		}
		
		if (!checkEmail(emailTextView.getText().toString())) {
			setEmailError();
			isLocallyValid = false;
		}

		if (isLocallyValid) {
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * Check if a email adress is valid
	 * 
	 * @param email to be verified
	 * @return True if the email is valid, false if isn't
	 */
	private boolean checkEmail(String email) {
        return EMAIL_ADDRESS_PATTERN.matcher(email).matches();
	}
	
	/***
	 * Set the borders around the edit texts to the default style
	 */
	private void resetErrorBorders() {
		usernameTextView.setBackgroundDrawable(originalEditTextDrawable);
		passwordTextView.setBackgroundDrawable(originalEditTextDrawable);
		repeatedPasswordTextView.setBackgroundDrawable(originalEditTextDrawable);
		emailTextView.setBackgroundDrawable(originalEditTextDrawable);
	}
	
	/***
	 * Set the dialog error body with the server error and color the fields
	 * correspondents edit text borders
	 */
	private void setServerError() {
		errorBody += getString(registryResult.getResultTextReference());
		switch(registryResult.getResultId()){
			case 116:
			case 114:	
				usernameTextView.setBackgroundResource(R.drawable.error_border);
				break;
			case 117:
				emailTextView.setBackgroundResource(R.drawable.error_border);
				break;
			default:
				emailTextView.setBackgroundResource(R.drawable.error_border);
				usernameTextView.setBackgroundResource(R.drawable.error_border);
				passwordTextView.setBackgroundResource(R.drawable.error_border);
				repeatedPasswordTextView.setBackgroundResource(R.drawable.error_border);				
				break;
		}
	}
	
	/***
	 * Set the dialog error body with the username error and color the username
	 * edit text borders
	 */
	private void setUserNameError() {
		errorBody +=  getString(R.string.username_error) + "\n";
		usernameTextView.setBackgroundResource(R.drawable.error_border);
	}

	/***
	 * Set the dialog error body with the password error and color the password
	 * edit text borders
	 */
	private void setPasswordError() {
		errorBody +=  getString(R.string.register_password_error) + "\n";
		passwordTextView.setBackgroundResource(R.drawable.error_border);
	}
	
	/***
	 * Set the dialog error body with the password error and color both password
	 * edit text borders
	 */
	private void setRepeatedPasswordError() {
		errorBody +=  getString(R.string.register_repeated_password_error) + "\n";
		passwordTextView.setBackgroundResource(R.drawable.error_border);
		repeatedPasswordTextView.setBackgroundResource(R.drawable.error_border);
	}
	
	/***
	 * Set the dialog error body with the email error and color the username
	 * edit text borders
	 */
	private void setEmailError() {
		errorBody +=  getString(R.string.email_error) + "\n";
		emailTextView.setBackgroundResource(R.drawable.error_border);
	}
	
	
}
